package com.ctvit.cch.core.task;

import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import com.ctvit.cch.ai.pojo.dto.AutoCategoryDTO;
import com.ctvit.cch.ai.pojo.dto.CreativeEvaluationDTO;
import com.ctvit.cch.ai.pojo.vo.AutoCategoryVO;
import com.ctvit.cch.ai.pojo.vo.CreativeEvaluationVO;
import com.ctvit.cch.ai.service.INlpService;
import com.ctvit.cch.core.pojo.domain.HotCategory;
import com.ctvit.cch.core.pojo.domain.HotRecord;
import com.ctvit.cch.core.service.IHotCategoryService;
import com.ctvit.cch.core.service.IHotRecordService;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ThreadMdcUtils;
import com.ruoyi.common.utils.ThreadPoolUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 创意评估任务
 *
 * @author heyingcheng
 * @date 2025/7/2
 */
@Slf4j
@Component("creativeEvaluationTask")
@ConditionalOnProperty(name = "cch.core.task.creative-evaluation.enabled", havingValue = "true")
public class CreativeEvaluationTask implements SchedulingConfigurer {

    private static final ThreadPoolTaskExecutor CREATIVE_EVALUATION_TASK_EXECUTOR = ThreadPoolUtils.create8ThreadPoolTaskExecutor();

    private static final String CRON_EXPRESSION = "0/5 * * * * ?";

    @Resource
    private IHotRecordService hotRecordService;
    @Resource
    private IHotCategoryService hotCategoryService;
    @Resource
    private INlpService nlpService;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(this::execute, triggerContext -> {
            CronTrigger trigger = new CronTrigger(CRON_EXPRESSION);
            return trigger.nextExecution(triggerContext);
        });
    }

    public void execute() {
        log.info("执行创意评估任务-开始");

        Map<String, Integer> categoryMap = hotCategoryService.list().stream().collect(Collectors.toMap(HotCategory::getCategoryName, HotCategory::getCategoryId));
        List<HotRecord> hostRecordList = hotRecordService.listByStatus(NumberUtils.INTEGER_MINUS_ONE.toString());
        List<CompletableFuture<Void>> completableFutures = new ArrayList<>(hostRecordList.size());
        for (HotRecord hotRecord : hostRecordList) {
            completableFutures.add(CompletableFuture.runAsync(ThreadMdcUtils.wrap(() -> evaluate(hotRecord, categoryMap)), CREATIVE_EVALUATION_TASK_EXECUTOR));
        }
        CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).join();

        log.info("执行创意评估任务-结束");
    }

    private void evaluate(HotRecord hotRecord, Map<String, Integer> categoryMap) {
        String recordId = hotRecord.getRecordId();
        try {
            String title = hotRecord.getTitle();
            String summary = hotRecord.getSummary();

            AutoCategoryVO acvo = nlpService.categorize(new AutoCategoryDTO(title, summary));
            String categoryName = acvo.getCategoryName();
            Integer categoryId = categoryMap.get(categoryName);
            if (Objects.isNull(categoryId)) {
                log.error("调用大模型进行自动分类错误, recordId:[{}], categoryName:[{}]", recordId, categoryName);
                return;
            }

            CreativeEvaluationVO cevo = nlpService.evaluate(new CreativeEvaluationDTO(title, summary));
            if (Objects.isNull(cevo)) {
                log.error("调用大模型进行创意评估错误, recordId:[{}]", recordId);
                return;
            }

            // 更新图片信息
            String httpImage = StringUtils.EMPTY;
            String rawImage = hotRecord.getRawImage();
            if (StringUtils.isNotBlank(rawImage)) {
                URL url = new URL(rawImage);
                String extension = FilenameUtils.getExtension(url.getPath());
                // 相对路径
                String relativeImage = StringUtils.format("upload/{}/{}_{}.{}", DateUtils.datePath(), HotRecord.class.getSimpleName(), IdUtils.fastSimpleUUID(), extension);
                String downloadImage = StringUtils.format("{}/{}", RuoYiConfig.getProfile(), relativeImage);
                long fileSize = HttpUtil.downloadFile(rawImage, FileUtil.file(downloadImage), 180000);
                if (fileSize > 0) {
                    httpImage = StringUtils.format("{}/{}", "http://localhost:8080/cch/profile", relativeImage);
                    hotRecord.setImage(downloadImage);
                }
            }

            HotRecord updateOne = assignHotRecord(hotRecord, categoryId, cevo, httpImage);
            hotRecordService.updateById(updateOne);
        } catch (Exception e) {
            log.error("执行创意评估异常, recordId:[{}]", recordId, e);
        }
    }

    private HotRecord assignHotRecord(HotRecord hotRecord, Integer categoryId, CreativeEvaluationVO cevo, String httpImage) {
        HotRecord updateOne = new HotRecord();
        updateOne.setRecordId(hotRecord.getRecordId());
        updateOne.setCategoryId(categoryId);
        updateOne.setImage(httpImage);
        updateOne.setSpreadWide(cevo.getSpreadWide());
        updateOne.setInfluenceDepth(cevo.getInfluenceDepth());
        updateOne.setCreativeValue(cevo.getCreativeValue());
        updateOne.setRecommendation(cevo.getRecommendation());
        updateOne.setStatus(NumberUtils.INTEGER_ZERO.toString());
        return updateOne;
    }

}
